﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SHomeWorkshop.LunarConcept.Enums;
using SHomeWorkshop.LunarConcept.Tools;
using System.Xml;
using SHomeWorkshop.LunarConcept.Controls;
using System.Windows.Shapes;
using System.Windows.Media;
using System.Windows;
using System.Windows.Controls;
using SHomeWorkshop.LunarConcept.Widgets.Interfaces;
using SHomeWorkshop.LunarMind;

namespace SHomeWorkshop.LunarConcept.Widgets
{
    /// <summary>
    /// 创建时间：2012年1月16日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：作为所有单线（带首尾箭头）的LineWidget的基类。
    /// </summary>
    public abstract class ArrowLineWidget : LineWidget, IWidgetPadding, IRadius
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// 构造方法。
        /// </summary>
        public ArrowLineWidget(PageEditorReader masterEditor)
            : base(masterEditor)
        {
            this.mainTextPanel.Margin = defaultBorderWidth;//取消Widget中设置的对于ArrowLineWidget的文本区域来说多余的margin。
            this.mainBorder.Child = this.mainTextPanel;
            this.mainCanvas.Children.Add(this.mainBorder);
            Canvas.SetZIndex(this.mainBorder, 2);

            this.layerIndex = WidgetLayerIndex.ArrowLineWidget;
            RefreshLayerIndex();
        }

        #endregion


        #region 字段与属性===================================================================================================


        protected ArrowType arrows = ArrowType.End;
        /// <summary>
        /// 默认值是尾箭头。这是考虑到用户的使用习惯。
        /// </summary>
        [Tools.LunarProperty("Arrows", PropertyDateType.ArrowType)]
        public ArrowType Arrows
        {
            get { return arrows; }
            set
            {
                arrows = value;
                if (this.xmlData != null)
                {
                    this.xmlData.SetAttribute("Arrows", value.ToString());
                }

                RefreshArrows();
            }
        }

        private static Thickness defaultBorderWidth = new Thickness(0);

        /// <summary>
        /// 包围文本区域的Border，目的是支持文本区域的内间距。
        /// </summary>
        protected Border mainBorder = new Border()
        {
            BorderThickness = defaultBorderWidth,
            Padding = defaultBorderWidth,
            BorderBrush = Brushes.Transparent,
            CornerRadius = new CornerRadius(16),
            Cursor = System.Windows.Input.Cursors.Hand,
        };

        public override System.Windows.Rect OuterRect
        {
            get { return new Rect(TopLeft, BottomRight); }
        }

        protected double radius = 0.0;
        /// <summary>
        /// [读写]是否圆角矩形。
        /// </summary>
        [Tools.LunarProperty("Radius", PropertyDateType.Double)]
        public double Radius
        {
            get
            {
                return this.radius;
            }
            set
            {
                radius = value;
                if (this.xmlData != null)
                {
                    this.xmlData.SetAttribute(XmlTags.RadiusTag, radius.ToString());
                }

                this.RefreshRadius(new Rect(Canvas.GetLeft(this.mainBorder),
                Canvas.GetTop(this.mainBorder), this.mainBorder.ActualWidth, this.mainBorder.ActualHeight));
            }
        }

        protected Path startArrowPath = new Path() { Visibility = Visibility.Hidden };//默认情况下不显示。

        protected Path endArrowPath = new Path();

        protected PathFigure startArrowPathFigure = new PathFigure();

        protected PathFigure endArrowPathFigure = new PathFigure();

        protected PolyLineSegment startArrowPolyLineSegment = new PolyLineSegment();

        protected PolyLineSegment endArrowPolyLineSegment = new PolyLineSegment();

        protected Thickness widgetPadding = new Thickness(0);
        /// <summary>
        /// [读写]部件内部空隙宽。默认值为0。
        /// </summary>
        [Tools.LunarProperty("WidgetPadding", PropertyDateType.Thickness)]
        public new Thickness WidgetPadding
        {
            get { return widgetPadding; }
            set
            {
                widgetPadding = value;
                if (this.xmlData != null)
                {
                    this.xmlData.SetAttribute(XmlTags.WidgetPadding, masterEditor.ThickConverter.ConvertToString(value));
                }
                this.RefreshWidgetPadding();

                //会影响圆角。
                this.RefreshRadius(new Rect(Canvas.GetLeft(this.mainBorder),
                    Canvas.GetTop(this.mainBorder), this.mainBorder.ActualWidth, this.mainBorder.ActualHeight));
            }
        }

        #endregion


        #region 方法=========================================================================================================


        public override void Build()
        {
            base.Build();

            if (this.xmlData == null) return;

            XmlAttribute attrArrows = this.xmlData.GetAttribute(XmlTags.ArrowsTag);
            if (attrArrows != null)
            {
                this.Arrows = (ArrowType)Enum.Parse(typeof(ArrowType), attrArrows.Value);
            }

            //此类是Arrows属性的“最终实现类”。因此调用，
            this.RefreshArrows();

            //因为这一分支的WidgetBackColor只管文本背景，因此，对这一分支来说，
            //此类就是WidgetBackColor属性的“最终实现类”。
            this.RefreshWidgetBackColor();
            this.RefreshWidgetPadding();

            //放在此类中，新添加的线条部件会无效，须放到具体实现类中去。
            //this.mainBorder.InvalidateArrange(); this.mainBorder.UpdateLayout();
            //this.RefreshRadius(new Rect(Canvas.GetLeft(this.mainBorder),
            //    Canvas.GetTop(this.mainBorder), this.mainBorder.ActualWidth, this.mainBorder.ActualHeight));
        }

        public virtual void RefreshArrows()
        {
            switch (arrows)
            {
                case ArrowType.All:
                    {
                        startArrowPath.Visibility = Visibility.Visible;
                        endArrowPath.Visibility = Visibility.Visible;
                        break;
                    }
                case ArrowType.Start:
                    {
                        startArrowPath.Visibility = Visibility.Visible;
                        endArrowPath.Visibility = Visibility.Hidden;
                        break;
                    }
                case ArrowType.End:
                    {
                        startArrowPath.Visibility = Visibility.Hidden;
                        endArrowPath.Visibility = Visibility.Visible;
                        break;
                    }
                default://无箭头
                    {
                        startArrowPath.Visibility = Visibility.Hidden;
                        endArrowPath.Visibility = Visibility.Hidden;
                        break;
                    }
            }
        }

        public override void RefreshWidgetLineWidth()
        {
            RefreshArrows();
        }

        /// <summary>
        /// ArrowLineWidget类的RefreshWidgetPadding()方法会在内部调用RefreshTextPanelLocatin()方法。
        /// </summary>
        public void RefreshWidgetPadding()
        {
            if (this.mainBorder != null)
                this.mainBorder.Padding = this.widgetPadding;

            this.mainBorder.InvalidateArrange();
            this.mainBorder.UpdateLayout();

            this.RefreshTextPanelLocatin();
        }

        public override void RefreshLocation()
        {
            base.RefreshLocation();
        }

        public override void RefreshIsShadowVisible()
        {
            if (isShadowVisible)
            {
                this.mainTextPanel.Effect =
                startArrowPath.Effect = endArrowPath.Effect = Widget.ShadowEffect;
            }
            else
            {
                this.mainTextPanel.Effect =
                startArrowPath.Effect = endArrowPath.Effect = null;
            }
        }

        public void RefreshRadius(Rect rect)
        {
            if (this.mainBorder == null) return;
            if (radius > 0)
            {
                double k;

                if (radius > 1)
                {
                    k = (radius % 1);//取小数。
                }
                else
                {
                    k = radius;
                }

                double r = Math.Min(rect.Width, rect.Height) * k;

                this.mainBorder.CornerRadius = new CornerRadius(r);
            }
            else
            {
                this.mainBorder.CornerRadius = new CornerRadius(0);
            }
        }

        public override void RefreshText()
        {
            base.RefreshText();

            this.mainBorder.InvalidateArrange();
            this.mainBorder.UpdateLayout();

            if (this.mainBorder.ActualHeight > 0 && this.mainBorder.ActualWidth > 0)
            {
                this.RefreshRadius(new Rect(Canvas.GetLeft(this.mainBorder),
                    Canvas.GetTop(this.mainBorder), this.mainBorder.ActualWidth, this.mainBorder.ActualHeight));
            }
        }

        /// <summary>
        /// WidgetBackground属性值改变时会调用此方法刷新部件的背景色。
        /// ——亦可根据需要调用。
        /// ——默认直接改变mainBorder的背景色。派生类可自行定义行为。
        /// </summary>
        public override void RefreshWidgetBackColor()
        {
            if (this.mainBorder != null)
                this.mainBorder.Background = widgetBackColor;
        }
        #endregion
    }
}
